"use strict"
const mvc = require("cosjs.mvc");
/**
 * @name battle
 * 战斗属性
 */
const BATTLERESULT = {};
/**
 * @name attr
 * @param json player 玩家:阵容，机器人前面加‘z’
 * 战斗属性
 */
exports.attr = async function () {
    let player = this.get('player', 'array');
    if (!Array.isArray(player) || player.length !== 2) {
        return this.error('player error', player)
    }
    let result = {};
    let i = 0

    for (let P of player) {
        if (!P['uid']) {
            return await Promise.reject('uid empty')
        }
        let id = P['uid'];
        let isRoboot = id.substr(0, 1) === 'z';

        P['debug_skill'] = P['debug_skill'] || ''
        P['debug_buff'] = P['debug_buff'] || ''

        let d

        if (isRoboot) {
            d = await this.library("attr/robot", id.substr(1), i++, P['debug_skill'].split(','), P['debug_buff'].split(','));
        } else {
            d = await this.library("attr/player", id, P['heroes'], P['equips'], P['pos'], [], {
                skill: P['debug_skill'].split(','),
                scale: P.scale
            }, P['debug_buff'].split(','));
        }

        delete d['debug_skill']
        delete d['debug_buff']
        result[id] = d;

    }

    if (Object.keys(result).length !== player.length) {
        return this.error("user not exist", player);
    } else {
        return result;
    }

}

/**
 * @name cache
 * 战斗结算
 */
exports.cache = async function () {
    //this.debug = 1;
    let battleData = this.get('battle', 'object');

    // let battleData = JSON.tryParse(battleStr)
    let battleCache = this.model.redis('battleCache', this.sid)
    let updater = this.library('updater', Object.keys(battleData['player'])[0], this.sid);

    updater.daily.set('bc', battleData.id)

    let ttl = 1 * 24 * 3600 //有效期1天
    await battleCache.set(battleData.id, JSON.stringify(battleData), ttl)

    return await updater.save()

}

/**
 * @name result
 * 战斗结算
 */
exports.result = function () {
    //this.debug = 1;
    let id = this.get('id', 'string');
    let bt = this.get('bt', 'int');
    let tar = this.get('tar', 'string');
    let win = this.get('win', 'string');
    // let attach = this.get('attach', 'string');
    let player = this.get('player', 'array');
    let heros = this.get('heros', 'json');
    let isAuto = this.get('isAuto', 'int');
    let isMagic = this.get('isMagic', 'int');
    let escape = this.get('escape', 'string');
    let round = this.get('round', 'int');

    let ladderAdIndex = this.get('ladderAdIndex', 'int');
    let ladderAdRecord = this.get('ladderAdRecord', 'array');
    let isRvg = this.get('isRvg', 'int');


    if (!id || !bt || !tar || !Array.isArray(player) || player.length !== 2) {
        return this.error('args error')
    }
    let battleData = {
        "bt": bt,
        "tar": tar,
        "win": win,
        "uid": [],
        "player": player,
        "isAuto": isAuto,
        "isMagic": isMagic,
        round: round,
        escape: escape,
        isRvg: isRvg,
        ladderAdIndex: ladderAdIndex,
        ladderAdRecord: ladderAdRecord
    };
    // if(rvg) {
    //     battleData['rvg'] = rvg
    // }
    // if(attach){
    //     battleData['attach'] = attach
    // }
    for (let d of player) {
        battleData['uid'].push(d['uid']);
        // battleData['hurt'].push(d['hurt']);
    }
    //console.log("battle result battleTypes",type,JSON.stringify(battleTypes))
    if (typeof BATTLERESULT[bt] !== 'function') {
        return this.error("battle bt not exist", bt);
    }
    let battleModel = this.model.mongo("battle", this.sid);
    return battleModel.get(id, ['bt', 'tar']).then(ret => {
        if (ret) {
            return this.error('battle exist', ret);
        }
        this.updater = this.library('updater', battleData['uid'][0], this.sid);
        this.updater.subverify = true;

        //清除战斗缓存记录
        this.updater.daily.set('bc', '')

        // if(battleData['win'] == this.updater.uid){
        //     record.call(this,player[0],player[1]);
        // }
        return BATTLERESULT[bt].call(this, id, battleData, heros);
    }).then(() => {
        delete battleData['player'];
        battleData['time'] = this.updater.time;
        battleData['result'] = this.updater.cache() || [];
        return battleModel.set(id, battleData);
    })
}
//剧情副本
BATTLERESULT[1] = function (id, battleData) {
    if (battleData['win'] !== this.updater.uid) {
        return;
    }
    this.updater.role.key('stage');
    let stageConfig = this.config("stage", battleData['tar']);
    if (!stageConfig) {
        return this.quick_error("M7GHLB123", 'config_not_exist', "stage", battleData['tar']);
    }
    this.updater.item.group(stageConfig['item']);
    return this.updater.data().then(() => {
        return this.library.call(this, "battle/stage_tail", Number(battleData['tar']), stageConfig);
    })
}

//南蛮入侵
BATTLERESULT[9] = async function (id, battleData) {
    let isWin = battleData['win'] === this.updater.uid;
    const tar = battleData['tar'];
    const eid = parseInt(tar);
    const _config = this.config("nmrqStage", eid);
    if (!_config) {
        return this.quick_error("M2GHLB1--1", "南蛮入侵关卡不存在", eid);
    }
    this.updater.role.key('nmrq', 'stage');
    await this.updater.data();
    //消耗
    if (isWin) {
        this.updater.sub(_config['sub']['id'], _config['sub']['num']);
    } else {
        this.updater.sub(_config['sub']['id'], _config['sub']['h']);
        return this.updater.save();
    }
    //role
    let nmrq = this.updater.role.get('nmrq');
    if (!nmrq) {
        return this.quick_error("M2GHLB1--2", "南蛮入侵没有记录");
    }
    if (_config.id > nmrq.level) {
        nmrq.level = _config.id;
        this.updater.role.set('nmrq', nmrq);
    }

    //奖励结算
    this.updater.item.group(_config['item']);
    return this.updater.save();
}


//每日玩法
BATTLERESULT[10] = async function (id, battleData) {

    const tar = battleData['tar'];
    const eid = Math.floor(parseInt(tar) / 1000);

    const _config = this.config("event", eid);
    if (!_config) {
        return this.quick_error("M2GHLB1", "config_not_exist", 'event', eid);
    }
    const etype = _config.type;
    const egid = "e" + eid;
    const typeConfig = this.config("eventType", _config.type);
    if (!typeConfig) {
        return this.quick_error("M2GHLB2", "config_not_exist", 'eventType', eid);
    }
    const robotConfig = this.config(typeConfig["config"], tar);
    if (!robotConfig) {
        return this.quick_error("M2GHLB3", "config_not_exist", typeConfig["config"], tar);
    }

    let killNum = 0;
    for (let P of battleData['player']) {
        if (P['uid'] != this.updater.uid) {
            killNum = P['DC'].length;
            break;
        }
    }

    // if (battleData['win'] !== this.updater.uid) {
    //     if((_config.type==5)&&killNum){
    //         //失败的时候 猛将无双也要结算击杀奖励
    //         for(let i=0;i<killNum;++i){
    //             this.updater.item.group(robotConfig['item']);
    //         }
    //         return this.updater.save();
    //     }else{
    //         return;
    //     }      
    // }

    let _isWin = battleData['win'] === this.updater.uid;

    const ek = ["events", eid].join(".");
    this.updater.role.key("stage", ek, robotConfig['gb']['id']);
    this.updater.daily.key("events");
    await this.updater.data();
    //role
    let info = this.updater.role.get(ek) || {};
    let dayInfo = this.updater.daily.get("events") || {};

    if (_isWin) {



        //BOBTODO 检查是前置关卡是否通关
        if (robotConfig.sort != 1) {
            if (!info[robotConfig.id - 1]) {
                return this.quick_error("M2GHLB311", "前置关卡未通关", robotConfig.id, robotConfig.id - 1);
            }
        }


        let _curStar = countStar(info[robotConfig.id] || 0);
        let _newStar = battleStar.call(this, battleData, robotConfig.star);
        let _getStar = _newStar[0] - _curStar;

        if (_newStar[0] > _curStar) {
            for (let i = _curStar; i < _newStar[0]; ++i) {
                //星级奖励
                this.updater.item.group(robotConfig.bonus[i]);
            }

        }

        info[robotConfig.id] = _newStar[1]//battleStar.call(this,battleData,robotConfig.star);

        if (_getStar) {
            this.updater.record.add(3000 + typeConfig.id * 100, _getStar);
        }


        if (!dayInfo[etype]) {
            dayInfo[etype] = 1;
        } else {
            dayInfo[etype]++;
        }

        if (!dayInfo[egid]) {
            dayInfo[egid] = 1;
        } else {
            dayInfo[egid]++;
        }
        this.updater.role.set(ek, info);
        this.updater.daily.set("events", dayInfo);
        //BOBTODO daily.events 的存储有问题，会
        // let dailyEvent=this.updater.daily.get('events')||{};

        // if(!dailyEvent[eid]){
        //     dailyEvent[eid]={};
        // }
        // if(dailyEvent[eid][robotConfig.id]){
        //     dailyEvent[eid][robotConfig.id]++;
        // }else{
        //     dailyEvent[eid][robotConfig.id]=1;
        // }
        // console.log(dailyEvent);
        // console.log(dailyEvent[eid][robotConfig.id]);
        // this.updater.daily.set('events',dailyEvent);
    }


    let mus = 1;
    let date = new Date();
    let day = date.getDay();
    if (day == 0) {
        day = 7;
    }
    if (_config.doubleTime.indexOf(day) != -1) {
        if (dayInfo[egid] <= _config.doubleNum) {
            mus = 2;
        }
    }



    return this.library.call(this, "battle/event_tail", _isWin, robotConfig, _config.type, mus);
}

//PVP天梯
BATTLERESULT[11] = function (id, battleData) {
    return this.library.call(this, 'ladder', id, battleData)
}

//挑战
BATTLERESULT[12] = async function (id, battleData) {

    const tar = battleData['tar'];
    const ctype = tar.split('|')[0];
    const fid = parseInt(tar.split('|')[1]);
    const _config = this.config(ctype, fid);
    if (!_config) {
        return this.quick_error("M2GHLB1", "config_not_exist", ctype, fid);
    }
    let _isWin = battleData['win'] === this.updater.uid;


    this.updater.role.key('challenge');
    this.updater.daily.key('chaNum');
    await this.updater.data();
    //消耗
    if (_isWin) {
        this.updater.sub(_config['sub']['id'], _config['sub']['num']);
    } else {
        this.updater.sub(_config['sub']['id'], _config['sub']['h']);
        return this.updater.save();
    }
    //role
    let cha = this.updater.role.get('challenge');

    if (!cha) {
        return this.quick_error("M2GHLB122", "挑战信息不存在");
    }
    let _curStar = countStar(cha[ctype]["levels"][fid] || 0);
    let _newStar = battleStar.call(this, battleData, _config.star);


    if (_newStar[0] > _curStar) {
        for (let i = _curStar; i < _newStar[0]; ++i) {
            //星级奖励
            if (_config && _config.bonus) {
                this.updater.item.group(_config.bonus[i]);
            }
        }
    }

    cha[ctype]["levels"][fid] = _newStar[1];
    this.updater.role.set('challenge', cha);
    //基本结算
    this.updater.item.group(_config['item']);
    let chaType = this.updater.daily.get('chaNum') || {};
    if (!chaType[ctype]) {
        chaType[ctype] = 0;
    }
    chaType[ctype]++;
    this.updater.daily.set('chaNum', chaType);
    return this.updater.save()
}

//结婚大作战
BATTLERESULT[13] = function (id, battleData) {
    return this.library.call(this, 'brideWar/result', id, battleData)
}

//3V3竞技场
BATTLERESULT[15] = function (id, battleData) {
    return this.library.call(this, 'ladderAd', id, battleData)
}


//剧情副本
BATTLERESULT[99] = function (id, battleData) {
    return
}


/**
 * 计算战斗星级
 * @param  battleData
 * @param  starConfig
 * @return array star
 */
function battleStar(battleData, configArr) {
    let star = [0, 0]
    for (let i in configArr) {
        let v = configArr[i]
        switch (v.id) {
            case 1:
                if (battleData.round <= v.val) {
                    star[0]++
                    star[1] += Math.pow(10, Number(i))
                }
                break;
            case 2:
                for (let P of battleData['player']) {
                    if (P['uid'] === this.updater.uid && P.DC.length <= v.val) {
                        star[0]++
                        star[1] += Math.pow(10, Number(i))
                    }
                }
                break;
            case 3:
                if (battleData.round <= v.val) {
                    star[0]++
                    star[1] += Math.pow(10, Number(i))
                }
                break;
            case 4:
                for (let P of battleData['player']) {
                    if (P['uid'] === this.updater.uid) {
                        let totalHp = 0
                        let totalMhp = 0
                        for (let id in P.heroes) {
                            totalHp += P.heros[id].hp
                            totalMhp += P.heros[id].totalMhp
                        }
                        if (totalHp / totalMhp >= v.val / 10000) {
                            star[0]++
                            star[1] += Math.pow(10, Number(i))
                        }
                    }
                }
                break;
            case 17:
                star[0]++
                star[1] += Math.pow(10, Number(i))
                break;
            default:

        }
    }
    return star
}


/**
 * 计算星级
 * @param  int starNumber
 * @return int star
 */
function countStar(star) {
    let b = parseInt(star / 100)
    let s = parseInt(star % 100 / 10)
    let g = parseInt(star % 100 % 10 / 1)
    return b + s + g
}